package com.cat2bug.junit.util;

import com.google.common.base.Strings;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Http Url网址工具
 */
public class UrlUtil {
    /**
     * 编译网址
     * @param url   源网址
     * @param pathVariable  路径注解
     * @param paramName     参数名
     * @param paramMethodName   替换的方法名
     * @return  网址
     */
    public static String compileUrl(String url, PathVariable pathVariable,String paramName,String paramMethodName) {
        String urlParamName =  pathVariable==null?null:pathVariable.value();
        urlParamName = Strings.isNullOrEmpty(urlParamName)? paramName:urlParamName;
        if(Strings.isNullOrEmpty(urlParamName)==false) {
            url = UrlUtil.pathParamHandler(url, urlParamName, String.format("this.%s()", paramMethodName));
        }
        return UrlUtil.handleUrl(url);
    }

    /**
     * 替换路径中的参数
     * @param url	源接口路径
     * @param name	需要替换的字段名
     * @param value	需要替换的字段值
     * @return	网址
     */
    private static String pathParamHandler(String url, String name, String value) {
        return url.replace(" ", "").replace("{" + name + "}","\n"+value+"\n");
    }

    /**
     * 处理网址中的各种问题
     * @param url   网址
     * @return  网址
     */
    private static String handleUrl(String url) {
        // 将路径中的执行方法结果转为字符串
        String newUrl = Arrays.stream(url.split("\n")).map(s->{
            if(s.matches("^(this\\.)([A-Za-z0-9]*)(\\(\\))$")) {
                return String.format("%s.toString()",s);
            } else {
                return "\""+s+"\"";
            }
        }).collect(Collectors.joining(" + "));

        // 由于有些接口中存在动态变量，但是在参数重又没有明确定义此变量，因此去掉带有{}的路径字符
        String pattern = "\\{([^{}]*)\\}";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(newUrl);

        StringBuffer sb = new StringBuffer();
        while (m.find()) {
            String placeholder = m.group(1); // 括号中的内容
            m.appendReplacement(sb, placeholder);
        }
        m.appendTail(sb);
        return sb.toString();
    }
}
